from typing import Annotated

from fastapi import APIRouter, Depends, Query, Request
from starlette.responses import HTMLResponse
from tortoise.expressions import Q
from tortoise.transactions import atomic

from applications import settings
from applications.common.render_template import templates
from applications.common.user_manager import manager, permission_depends
from applications.utils.http import PageResponse, ResultResponse, fail_api, success_api, table_api
from applications.models import LoginLog, Role, User
from applications.schemas.admin_user import (
    EnableDisableUserSchema,
    UpdateAvatarSchema,
    UpdateInfoSchema,
    UpdatePasswordSchema,
    UserAddSchema,
    UserOut,
    UserQueryParams,
    UserUpdateSchema,
)

route = APIRouter(prefix="/user", tags=["系统管理-用户管理"])


# 用户管理
@route.get(
    "/",
    name="system.user.main",
    dependencies=[Depends(permission_depends("system:user:main"))],
    response_class=HTMLResponse,
    include_in_schema=False,
)
async def main(request: Request):
    return templates.TemplateResponse(request=request, name="system/user/main.html")


#   用户分页查询
@route.get(
    "/data",
    dependencies=[Depends(permission_depends("system:user:main"))],
    summary="获取用户列表",
    response_model=PageResponse[UserOut],
)
async def get_user_list(params: Annotated[UserQueryParams, Query()]):
    # 获取请求参数
    query = Q()
    if params.realname:
        query &= Q(realname__contains=params.realname)
    if params.username:
        query &= Q(username__contains=params.username)
    if params.deptId:
        query &= Q(dept_id=params.deptId)

    users = (
        await User.filter(query)
        .offset(params.page - 1)
        .limit(params.limit)
        .prefetch_related("dept")
        .values(
            "id",
            "username",
            "realname",
            "enable",
            "create_at",
            "update_at",
            dept_name="dept__dept_name",
            dept_id="dept__id",
        )
    )
    count = await User.filter(query).count()

    return table_api(
        data=users,
        count=count,
    )


# 用户增加
@route.get(
    "/add",
    dependencies=[Depends(permission_depends("system:user:add"))],
    response_class=HTMLResponse,
    include_in_schema=False,
)
async def add(request: Request):
    roles = await Role.all()
    return templates.TemplateResponse("system/user/add.html", {"request": request, "roles": roles})


@route.post(
    "/save",
    dependencies=[Depends(permission_depends("system:user:add"))],
    summary="保存用户",
    response_model=ResultResponse,
)
@atomic()
async def save(data: UserAddSchema):
    role_ids = data.roleIds.split(",")

    if bool(await User.filter(username=data.username).count()):
        return fail_api(msg="用户已经存在")

    user = User(**data.model_dump(exclude={"roleIds"}))
    user.set_password(data.password)

    roles = await Role.filter(id__in=role_ids).all()
    await user.save()
    await user.roles.add(*roles)

    return success_api(msg="增加成功")


# 删除用户
@route.delete(
    "/remove/{pk}",
    dependencies=[Depends(permission_depends("system:user:remove"))],
    summary="删除用户",
    response_model=ResultResponse,
)
async def delete(pk: int):
    user = await User.get_or_none(id=pk)
    if user is None:
        return fail_api(msg="用户不存在")
    await user.delete()
    return success_api(msg="删除成功")


#  编辑用户
@route.get(
    "/edit/{pk}",
    dependencies=[Depends(permission_depends("system:user:edit"))],
    response_class=HTMLResponse,
    include_in_schema=False,
)
async def edit(request: Request, pk: int):
    user = await User.get(id=pk)
    roles = await Role.all()

    await user.fetch_related("roles")
    user_roles = await user.roles.all()
    checked_roles = [r.id for r in user_roles]
    return templates.TemplateResponse(
        "system/user/edit.html", {"request": request, "user": user, "roles": roles, "checked_roles": checked_roles}
    )


#  编辑用户
@route.put(
    "/update",
    dependencies=[Depends(permission_depends("system:user:edit"))],
    summary="更新用户",
    response_model=ResultResponse,
)
@atomic()
async def update(user: UserUpdateSchema):
    # 获取用户信息
    user_obj = await User.get_or_none(id=user.userId)
    if not user_obj:
        return fail_api(msg="用户不存在")

    # 更新用户基本信息
    user_obj.username = user.username
    user_obj.realname = user.realname
    user_obj.dept_id = user.deptId

    # 更新用户角色关联
    role_ids = user.roleIds.split(",") if isinstance(user.roleIds, str) else user.roleIds
    role_ids = [int(role_id) for role_id in role_ids if role_id.isdigit()]

    # 清除现有角色关联
    await user_obj.roles.clear()

    # 添加新角色关联
    if role_ids:
        roles = await Role.filter(id__in=role_ids).all()
        if roles:
            await user_obj.roles.add(*roles)

    # 保存更新
    await user_obj.save()

    return success_api(msg="更新成功")


# 个人中心
@route.get("/center", response_class=HTMLResponse, include_in_schema=False)
async def center(request: Request, user: User = Depends(manager)):
    user_info = user
    user_logs = await LoginLog.filter(user_id=user_info.id).order_by("-create_time").limit(10)
    return templates.TemplateResponse(
        "system/user/center.html", {"request": request, "user_info": user_info, "user_logs": user_logs}
    )


# 修改头像
@route.get("/profile", dependencies=[Depends(manager)], response_class=HTMLResponse, include_in_schema=False)
async def profile(request: Request):
    return templates.TemplateResponse("system/user/profile.html", {"request": request})


# 修改头像
@route.put(
    "/updateAvatar",
    dependencies=[Depends(permission_depends("system:user:edit"))],
    summary="更新用户头像",
    response_model=ResultResponse,
)
async def update_avatar(avatar_data: UpdateAvatarSchema, user: User = Depends(manager)):
    url = avatar_data.avatar.get("src")

    # 更新用户头像
    user.avatar = url
    await user.save()

    return success_api(msg="修改成功")


# 修改当前用户信息
@route.put(
    "/updateInfo",
    dependencies=[Depends(permission_depends("system:user:edit"))],
    summary="更新用户信息",
    response_model=ResultResponse,
)
async def update_info(info_data: UpdateInfoSchema, user: User = Depends(manager)):
    user.realname = info_data.realName
    user.remark = info_data.details

    await user.save()

    return success_api(msg="更新成功")


# 修改当前用户密码
@route.get(
    "/editPassword",
    dependencies=[Depends(permission_depends("system:user:edit"))],
    response_class=HTMLResponse,
    include_in_schema=False,
)
async def edit_password(request: Request):
    return templates.TemplateResponse("system/user/edit_password.html", {"request": request})


# 修改当前用户密码
@route.put(
    "/editPassword",
    dependencies=[Depends(permission_depends("system:user:edit"))],
    summary="修改用户密码",
    response_model=ResultResponse,
)
async def edit_password_put(password_data: UpdatePasswordSchema, user: User = Depends(manager)):
    is_right = user.validate_password(password_data.oldPassword)
    if not is_right:
        return fail_api("旧密码错误")

    user.set_password(password_data.newPassword)
    await user.save()

    return success_api("更改成功")


# 启用用户
@route.put(
    "/enable",
    dependencies=[Depends(permission_depends("system:user:edit"))],
    summary="启用用户",
    response_model=ResultResponse,
)
async def enable(enable_data: EnableDisableUserSchema):
    _id = enable_data.userId

    user = await User.get_or_none(id=_id)
    if not user:
        return fail_api(msg="用户不存在")
    if user.enable == 1:
        return fail_api(msg="用户已经启动")
    user.enable = 1
    await user.save()

    return success_api(msg="启动成功")


# 禁用用户
@route.put(
    "/disable",
    summary="禁用用户",
    response_model=ResultResponse,
)
async def dis_enable(
    disable_data: EnableDisableUserSchema, user: User = Depends(permission_depends("system:user:edit"))
):
    _id = disable_data.userId
    if user.id == _id:
        return fail_api(msg="不能禁用自己")
    user = await User.get_or_none(id=_id)
    if user.username == settings.SUPERADMIN:
        return fail_api(msg="超级管理员不能禁用")
    if not user:
        return fail_api(msg="用户不存在")
    if user.enable == 0:
        return fail_api(msg="用户已经禁用")
    user.enable = 0
    await user.save()

    return success_api(msg="禁用成功")
